package mazewar.legacy;



import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;



/**
 * @author jillsanluis
 */
public class NetworkServerThread extends Thread {

    /** Server managing this Thread */
    private NetworkServer server;
    /** Socket associated with this Thread*/
    private Socket socket;
    /** Index of this Thread in the server Thread list*/
    private Integer id;
    /** InputStream for receiving packets from this client */
    private ObjectInputStream fromClient;
    /** OutputStream for sending packets to this client */
    private ObjectOutputStream toClient;

    private String key;
    private String rawName;
    private DirectedPoint directedPoint;
    
    /**
     * Creates an instance of MazeWarServerHandlerThread.
     * 
     * @param server    managing this Thread
     * @param socket    of associated with this Thread
     */
    public NetworkServerThread(NetworkServer server, Socket socket) {
        this.server = server;
        this.socket = socket;
        this.id = socket.getPort();
    }

    /**
     * @return ID    of this Thread
     */
    public Integer getID() {
        return id;
    }

    /**
     * Runs this instance of MazeWarServerHandlerThread.
     */
    @Override
    public void run(){

        System.out.println("Server Thread " + id + " running.");

        while(true){
            try{
                NetworkPacket fromClientPacket = (NetworkPacket) fromClient.readObject();

                if(fromClientPacket.getSrcInput() == ClientSessionInput.JOIN){
                    key = fromClientPacket.getSrcName()+ " " + fromClientPacket.getSrcSocket();
                    rawName = fromClientPacket.getSrcName();
                }
                
                server.handle(id, fromClientPacket);
            }
            catch(IOException e){
                System.out.println(id + " ERROR reading: " + e.getMessage());
                server.remove(id);
                break;
            }
            catch(ClassNotFoundException e){
                System.err.println(e.getMessage());
                server.remove(id);
                break;
            }
        }
    }
    
    /**
     * Opens socket's InputStream and OutputStream
     *
     * @throws IOException  I/O error occurs while reading or writing stream header
     */
    public void open() throws IOException {
        fromClient = new ObjectInputStream(socket.getInputStream());
        toClient = new ObjectOutputStream(socket.getOutputStream());
    }

    /**
     * Sends the broadcast packet from server to the destination client(represented by this Thread).
     *
     * @param packetToClient    broadcast packet from server
     *
     * @throws IOException      failure to write object to OutputStream
     */
    public void send(NetworkPacket packetToClient) throws IOException {
       toClient.writeObject(packetToClient);
    }

    /**
     * Closes initialized Socket, InputStream, and OutputStream.
     * 
     * @throws IOException  failure to close initialized Socket or Streams
     */
    public void close() throws IOException{
        if(socket != null){
            socket.close();
        }

        if(fromClient != null){
            fromClient.close();
        }

        if(toClient != null){
            toClient.close();
        }
    }

    /**
     * @return the name
     */
    public String getClientKey() {
        return key;
    }
    
    public String getRawName() {
    	return rawName;
    }

    public void setDirectedPoint(DirectedPoint directedPoint){
        this.directedPoint =directedPoint;
    }

    public DirectedPoint getDirectedPoint(){
        return directedPoint;
    }
}
